iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 16
2
Security

CTF 的三十道陰影系列 第 16

Day16: [Pwn] Educational Heap Exploitation

  • 分享至 

  • xImage
  •  

前言

最近在找回荒廢已久的解題技能...QQ 從工作之後就越來越生疏了,尤其進入 tcache 時代就幾乎沒有認真研究過,這幾天都在重新學習 T___T

不過今天的文章還是不會講得太深入就是了,只會大概提一下 CTF 中有哪些 heap 的玩法,如果要了解詳細原理,請直接點參考資料

Educational Heap Exploitation

這是一份由 CTF 隊伍 shellphish 編輯的 heap 教材,上面已經整理了目前已知的 heap 玩法和各種用 C 語言寫的範例,還有統整以前有哪些 CTF 題目考過,最重要的是,還有附註哪些 glibc 版本才適用 XD 對有一陣子沒碰 heap exp 的我真的太有幫助了,但因為缺乏視覺化的關係,對新手其實不好理解,如果是第一次學習的人可能還是要看視覺化的教材會比較容易明白,接下來會盡量以淺顯易懂的方式解釋這些 heap 玩法

Heap exploit

1. first_fit.c

  • 說明 ptmalloc 在 size 相同時會返回同一塊 heap chunk
  • 範例 code 存在 UAF 的漏洞

2. fastbin_dup.c

  • 示範 fastbin 因為檢查不嚴謹,允許 double free 並讓兩次 malloc 取得同一塊 heap chunk
  • 範例 code 存在 UAF 導致的 double free 漏洞

3. fastbin_dup_into_stack.c

  • 跟 fastbin_dup.c 類似,但更改 UAF 的利用方式
  • 修改 fd 到 stack 上偽造的 chunk,讓之後的 malloc 可以取得 stack 上偽造的 chunk
  • 不一定是 stack,任何可偽造 chunk 的位置都可以
  • 又被稱為 fastbin corruption
  • 範例 code 存在 UAF,可以對 freed chunk 寫入資料

4. fastbin_dup_consolidate.c

  • fastbin_dup_into_stack.c 的進階利用方式
  • fastbin 不能連續 free 兩次同一個 chunk
  • 利用 malloc_consolidate 時會將 last_reminder 放進 unsorted bin 的特性,造成 fastbin 和 unsorted bin 儲存同一塊 chunk
  • 範例 code 存在 UAF 導致的 double free 漏洞

5. house_of_spirit.c

  • 跟 fastbin_dup_into_stack.c 類似,但變成在 free 之前偽造 chunk
  • fastbin 是單向的 linked listed,free 之前只會檢查兩點:
    1. chunk 的 size 是否正確
    2. 不能是 fastbin list 的第一個
  • 因此在任意位置偽造 chunk 之後,可以丟進 fastbin 在之後 malloc 取得

6. overlapping_chunks_2.c

  • 原理是 heap chunk 分配之後在記憶體中會是連續分配,將第一塊 chunk 的 size 改大再 free 掉,ptmalloc 會認為中間的 chunk 都是第一個 chunk 的 buffer 區段,一併放進 freed list 裡面,此時如果再操作中間的 chunk 就可以達成類似 UAF 的效果
  • 範例 code 直接修改 第一塊 chunk 的 size,通常會視發生 heap overflow 導致前面的 chunk 可以往後蓋修改到 size

上述的六種利用方式一直到目前最新的 glibc 版本都可以利用,利用難度也相對簡單,明天再繼續講剩下的幾種方式 XD

參考資料

0x0f: Hack.lu CTF 2014: OREO

今天要介紹的這題 OREO 可以說是 pwn 題的先驅,當年 pwn 題大家還不流行玩 heap,大家就頂多玩到以前 dlmalloc 的 unlink 造成任意寫入,這題可以說是當年讓大家耳目一新,也開始將 ptmalloc 的玩法出成 CTF 題,像是 phrack 的這份文件:http://phrack.org/issues/66/10.html


這題是 32 bit,保護只有 NX 和 PIE,功能是典型的選單題,功能有六個:

  1. Add new rifle
    • malloc 一個 0x38 的 chunk,程式會用 linked list 儲存,最後 4 byte 是 prev 指向前一個 rifle
    • 新增之後會增加 bss 上變數 rifles_cnt 的值
    • fgets 讀取內容時也讀取 0x38,因此我們可以把 prev 覆蓋成想要的 address
  2. Show added rifles
    • 將 rifles 的內容印出來
  3. Order selected rifles
    • 遍歷所有 linked list 把 rifles 給 free 掉
    • 每 free 一個 rifles 會減少 rifles_cnt 的值,增加另一個 bss 變數 order_cnt
  4. Leave a Message with your Order
    • 可以寫 128 byte 的字串在 bss 的 buffer 上
    • 故意用了一個指標指向 bss buffer
  5. Show current stat
    • 將目前 rifles 的數量以及使用 4. 留下的訊息印出
    • 印出訊息時是用指標印出
  6. Exit!
    • 毫無反應,就是結束程式

這個程式上 bss 的結構長這樣:

int order_cnt;
int rifles_cnt;
char *msg_ptr;
char msg_buf[128];

利用 2. 的功能可以輕鬆將 heap 的 address 給印出來,加上 1. 輸入 data 可以覆蓋掉 prev,我們可以用今天文章提到的 House of Spirit,將在 4. 留訊息的功能偽造 fastbin chunk,加入 prev 後 free 掉,然後再一次利用 4. 的功能改寫 fastbin 的 fd,利用 order_cntrifles_cnt 偽造成 chunk prev_size 和 size,將 fd 改成 &order_cnt 的位置之後,我們就能再 malloc 兩次就能改寫掉 msg_ptr 的值,接下來 4. 和 5. 的功能就變成任意 address 的讀寫了

這題因為沒有給 libc (當年的題目很喜歡不給 libc QQ),後續利用還是有一些麻煩,要 leak linkmap 之後做 ret2dl-resolve 才能 call system,但以現在 pwn 題的水準來看,簡直是送分題了.....XDD 現在拜 angelboy 所賜,沒有保護全開的 heap 題已經不能拿出來放了,讓我們一起緬懷過去拿個美好而單純的年代 (誤


上一篇
Day15: [Pwn] DEFKOR & Cykor
下一篇
Day17: [Pwn] Educational Heap Exploitation - part 2
系列文
CTF 的三十道陰影31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言